# coding=utf-8
# Copyright 2018-2023 EvaDB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from sqlalchemy.types import Enum

from evadb.catalog.catalog_type import VectorStoreType
from evadb.catalog.models.base_model import BaseModel
from evadb.catalog.models.utils import IndexCatalogEntry


class IndexCatalog(BaseModel):
    """The `IndexCatalogEntry` catalog stores information about all the indexes in the system.
    `_row_id:` an autogenerated unique identifier.
    `_name:` the name of the index.
    `_save_file_path:` the path to the index file on disk
    `_type:` the type of the index (refer to `VectorStoreType`)
    `_feat_column_id:` the `_row_id` of the `ColumnCatalog` entry for the column on which the index is built.
    `_function_signature:` if the index is created by running function expression on input column, this will store
                      the function signature of the used function. Otherwise, this field is None.
    `_index_def:` the original SQL statement that is used to create this index. We record this to rerun create index
                on updated table.
    """

    __tablename__ = "index_catalog"

    _name = Column("name", String(100), unique=True)
    _save_file_path = Column("save_file_path", String(128))
    _type = Column("type", Enum(VectorStoreType), default=Enum)
    _feat_column_id = Column(
        "column_id", Integer, ForeignKey("column_catalog._row_id", ondelete="CASCADE")
    )
    _function_signature = Column("function", String, default=None)
    _index_def = Column("index_def", String, default=None)

    _feat_column = relationship(
        "ColumnCatalog",
        back_populates="_index_column",
    )

    def __init__(
        self,
        name: str,
        save_file_path: str,
        type: VectorStoreType,
        feat_column_id: int = None,
        function_signature: str = None,
        index_def: str = None,
    ):
        self._name = name
        self._save_file_path = save_file_path
        self._type = type
        self._feat_column_id = feat_column_id
        self._function_signature = function_signature
        self._index_def = index_def

    def as_dataclass(self) -> "IndexCatalogEntry":
        feat_column = self._feat_column.as_dataclass() if self._feat_column else None
        return IndexCatalogEntry(
            row_id=self._row_id,
            name=self._name,
            save_file_path=self._save_file_path,
            type=self._type,
            feat_column_id=self._feat_column_id,
            function_signature=self._function_signature,
            index_def=self._index_def,
            feat_column=feat_column,
        )
